package com.mbc.web.common.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.mbc.web.common.shared.HttpStatus;
import com.mbc.common.entities.Branch;
import com.mbc.common.entities.Role;
import com.mbc.common.entities.User;
import com.mbc.common.entities.UserInOffices;
import com.mbc.common.entities.UserInRoles;
import com.mbc.web.common.client.ButtonActionType;
import com.mbc.web.common.client.ClientSingleton;
import com.mbc.web.common.client.CommonControllerMgr;
import com.mbc.web.common.client.CommonMessage;
import com.mbc.web.common.client.ViewUtils;
import com.mbc.web.common.client.ui.control.MButton;
import com.mbc.web.common.client.ui.control.MListBox;
import com.mbc.web.common.client.ui.control.MPasswordTextBox;
import com.mbc.web.common.client.ui.control.MTextBox;
import com.mbc.web.common.shared.dto.UserViewLoadDTO;

public class FrmUser extends Composite {

	private static FrmUserUiBinder uiBinder = GWT.create(FrmUserUiBinder.class);
	@UiField MTextBox txtLoginId;
	@UiField MListBox listRole;
	@UiField MTextBox txtUserName;
	@UiField MListBox listBranch;
	@UiField MPasswordTextBox txtPassword;
	@UiField MPasswordTextBox txtConfirmPassword;
	@UiField MButton btnSave;
	@UiField MButton btnEdit;
	@UiField MButton btnDelete;
	@UiField MButton btnReset;
	@UiField MButton btnNew;
	@UiField MButton btnBack;

	private long userId;
	private User user;
	private byte action_type;
	
	interface FrmUserUiBinder extends UiBinder<Widget, FrmUser> {
	}

	public FrmUser() {
		initWidget(uiBinder.createAndBindUi(this));
		FormLoad();
		onBtnNewClick(null);
	}
	
	public FrmUser(User user) {
		initWidget(uiBinder.createAndBindUi(this));
		FormLoad();
		this.user = user;
		enableControls(false);
		btnSave.setEnabled(false);
		btnEdit.setEnabled(true);
		btnDelete.setEnabled(true);
		btnReset.setEnabled(false);
	}

	private void FormLoad()
	{
		txtLoginId.getElement().setAttribute("style", "text-transform: uppercase;");
		user = new User();
		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			
			@Override
			public void execute() {
				txtLoginId.setFocus(true);
			}
		});
		
		CommonControllerMgr.getUserViewLoadData(getUserViewLoadDataCallback());
	}
	
	private AsyncCallback<UserViewLoadDTO> getUserViewLoadDataCallback(){
		return new AsyncCallback<UserViewLoadDTO>() {
			
			@Override
			public void onSuccess(UserViewLoadDTO result) {
				if(result.getHttpStatus() == HttpStatus.OK){
					for (Role l_role : result.getRoleList()) {
						listRole.addItem(l_role.getRoleName(), String.valueOf(l_role.getRoleID()));
					}
					for (Branch l_Branch : result.getBranchList()) {
						listBranch.addItem(l_Branch.getName(), String.valueOf(l_Branch.getBranchId()));
					}
					if(user != null)
					{
						bindControls(user);
						enableControls(false);
						btnSave.setEnabled(false);
						btnEdit.setEnabled(true);
						btnDelete.setEnabled(true);
						btnReset.setEnabled(false);
					}
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		};
	}
	
	private void enableControls(boolean enabled)
	{
		txtLoginId.setEnabled(enabled);
		txtPassword.setEnabled(enabled);
		txtUserName.setEnabled(enabled);
		txtConfirmPassword.setEnabled(enabled);
		listRole.setEnabled(enabled);
		listBranch.setEnabled(enabled);
	}
	
	private void clear(){
		jsClear();
		ViewUtils.clearRequiredNotifications();
		user = null;
		userId = 0;
	}
	
	private native void jsClear()/*-{
		$wnd.$("input").val("");
		$wnd.$("select").prop('selectedIndex','0');
	}-*/;
	
	private void bindControls(User user){
		userId = user.getUserId();
		txtLoginId.setText(user.getLoginId());
		txtUserName.setText(user.getUserName());
		txtPassword.setText(user.getPassword());
		txtConfirmPassword.setText(txtPassword.getText());
		
		for (int i = 0; i < listBranch.getItemCount(); i++) {
			if(Long.parseLong(listBranch.getValue(i)) == user.getUserInOfficeList().get(0).getOfficeId()){
				listBranch.setSelectedIndex(i);
				break;
			}
		}
		
		for (int i = 0; i < listRole.getItemCount(); i++) {
			if(Long.parseLong(listRole.getValue(i)) == user.getUserInRolesList().get(0).getRoleId()){
				listRole.setSelectedIndex(i);
				break;
			}
		}
		
		
	}
	
	private User bindUser(){
		User l_user = new User();
		l_user.setUserId(userId);
		l_user.setLoginId(txtLoginId.getText());
		l_user.setUserName(txtUserName.getText());
		l_user.setPassword(txtPassword.getText());
		
		UserInRoles l_UserInRole = new UserInRoles();
		l_UserInRole.setRoleId(Long.parseLong(listRole.getValue(listRole.getSelectedIndex())));
		l_user.getUserInRolesList().add(l_UserInRole);
		
		UserInOffices l_UserInOffices = new UserInOffices();
		l_UserInOffices.setOfficeId(Long.parseLong(listBranch.getValue(listBranch.getSelectedIndex())));
		l_user.getUserInOfficeList().add(l_UserInOffices);
		
		return l_user;
	}
	
	private AsyncCallback<Integer> actionCallback()
	{
		return new AsyncCallback<Integer>() {
			
			@Override
			public void onSuccess(Integer result) {
				ViewUtils.stopAjaxLoader();
				if(result == HttpStatus.OK){
					switch (action_type) {
					case ButtonActionType.action_save:
						ViewUtils.showSuccessMessage(CommonMessage.saved_message);
						ClientSingleton.changeView(new SearchUser(txtLoginId.getText(), SearchUser.SAVE));
						break;
					case ButtonActionType.action_delete:
						ViewUtils.showSuccessMessage(CommonMessage.deleted_message);
						ClientSingleton.changeView(new SearchUser(txtLoginId.getText(), SearchUser.DELETE));
						break;
					}
				}
				else{
					if(result == HttpStatus.INTERNAL_SERVER_ERROR)
						ViewUtils.showErrorMessage(CommonMessage.internal_server_error_message);
					else if(result == HttpStatus.BAD_REQUEST)
						ViewUtils.showErrorMessage(CommonMessage.getAlreadyExistedMessage("Login Id(" + txtLoginId.getText() + ")"));
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		};
	}
	
	private AsyncCallback<User> getUserCallback(){
		return new AsyncCallback<User>() {
			
			@Override
			public void onSuccess(User result) {
				ViewUtils.stopAjaxLoader();
				if(result != null)
				{
					enableControls(false);
					user = result;
					bindControls(user);
					btnSave.setEnabled(false);
					btnEdit.setEnabled(true);
					btnDelete.setEnabled(true);
					btnNew.setEnabled(true);
					btnReset.setEnabled(false);
				}
				else{
					
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		};
	}
	
	@UiHandler("btnNew")
	void onBtnNewClick(ClickEvent event) {
		clear();
		
		enableControls(true);
		
		txtLoginId.setFocus(true);
		btnSave.setEnabled(true);
		btnEdit.setEnabled(false);
		btnDelete.setEnabled(false);
		btnReset.setEnabled(false);
	}
	
	@UiHandler("btnSave")
	void onBtnSaveClick(ClickEvent event) {
		if(ViewUtils.isValidate())
		{
			action_type = ButtonActionType.action_save;
			ViewUtils.startAjaxLoader(CommonMessage.saving_message);
			if(userId == 0)
				CommonControllerMgr.createUser(bindUser(), actionCallback());
			else
				CommonControllerMgr.updateUser(bindUser(), actionCallback());
		}
	}
	
	@UiHandler("btnEdit")
	void onBtnEditClick(ClickEvent event) {
		if(userId != 0){
			btnReset.setEnabled(true);
			btnSave.setEnabled(true);
			btnEdit.setEnabled(false);
			btnNew.setEnabled(false);
			enableControls(true);
			txtUserName.setFocus(true);
			txtLoginId.setEnabled(false);
		}
	}
	
	@UiHandler("btnDelete")
	void onBtnDeleteClick(ClickEvent event) {
		if(userId != 0)
		{
			ViewUtils.showConfirm(CommonMessage.delete_confirm_message, new CloseHandler<PopupPanel>() {
				
				@Override
				public void onClose(CloseEvent<PopupPanel> event) {
					if(ViewUtils.isAlertYes()){
						action_type = ButtonActionType.action_delete;
						ViewUtils.startAjaxLoader(CommonMessage.deleting_message);
						CommonControllerMgr.deleteUser(userId, actionCallback());
					}
				}
			});
		}
	}
	
	@UiHandler("btnReset")
	void onBtnResetClick(ClickEvent event) {
		bindControls(user);
		enableControls(false);
		btnReset.setEnabled(false);
		btnSave.setEnabled(false);
		btnEdit.setEnabled(true);
		btnNew.setEnabled(true);
	}
	
	@UiHandler("btnBack")
	void onBtnBackClick(ClickEvent event) {
		ClientSingleton.changeView(new SearchUser());
	}
}
